package cn.biplam.back.operator.tree;

import java.util.ArrayList;

import cn.biplam.common.client.DataFilter;
import cn.biplam.common.client.DbResource;
import cn.biplam.common.client.Operator;
import cn.biplam.common.client.OperatorResult;
import cn.biplam.common.opcode.SysManageCode.TreeIndexCode;
import cn.biplam.common.tools.TOOLS;
import cn.biplam.common.wrapper.ErrorMessage;
import cn.biplam.common.wrapper.tree.TreeIndexFields;

/**
 *  索引树数据操作—查询节点数据
 * @author XiaoRuxing Nov 12, 20094:34:52 PM
 * @version 1.0
 */
public class OptIndexTreeSelect extends IndexTree{

	protected OptIndexTreeSelect(String userId, String tableName,
			TreeIndexFields fields, DbResource dbResource) {
		super(userId, tableName, fields, dbResource);
	}

	/**
	 * 获取离指定节点最近的节点，如果节点没有兄弟则最近为节点的父亲，如果有哥哥节点则最近为哥哥，如果无哥哥节点则最近为弟弟
	 * @param sql    
	 * @param filter 过滤器 参数：当前节点ID
	 * @throws ErrorMessage 
	 */
	public void getNearestNode(ArrayList<String> sql,DataFilter filter) throws ErrorMessage{
		/** 查询当前节点信息 */
		OperatorResult sr=Operator.get(TreeIndexCode.Select_Node, this.userId, filter,this.dbResource);
		String curNode = sr.getValue(this.fields.getNodeId());
		String parentID = sr.getValue(this.fields.getNodeParent());
		String nodeType = sr.getValue(this.fields.getNodeType());
		//获取当前节点的兄弟
		OperatorResult siblings = this.getSibling(parentID, nodeType, null);
		String nearNode = null;
		//如果存在兄弟最近节点为兄弟节点,否则最近节点为父亲节点
		if(TOOLS.exist(siblings)
				&& siblings.size()>1){
			nearNode = getNodeBrohter(siblings, curNode);
		}else{
			nearNode = parentID;
		}
		//查询最近节点信息
		getNodeById(sql, nearNode);
	}
	
	/**
	 * 根据节点ID获取节点信息
	 * @throws ErrorMessage 
	 */
	protected void getNodeById(ArrayList<String> sql,String nodeId) throws ErrorMessage{
		StringBuilder sp=new StringBuilder();
		sp.append(" select * from ");
		sp.append(this.tableName);
		sp.append(" where ");
		sp.append(this.fields.getNodeId());
		sp.append("='");
		sp.append(nodeId);
		sp.append("'");
		sql.add(sp.toString());
	}
	
	//获取节点的哥哥
	private String getNodeBrohter(OperatorResult siblings, //节点所有兄弟
			String curNode//节点ID
			) throws ErrorMessage{
		String brother = null;
		String newNode = null;
		String firstSib = siblings.getValue(this.fields.getNodeId());//获取兄弟中的老大
		brother = firstSib;//初始化哥哥为兄弟中的老大
		//如果当前节点为兄弟中的老大返回节点的弟弟
		if(firstSib.equals(curNode)){
			siblings.next();
			return siblings.getValue(this.fields.getNodeId());
		}
		//如果当前节点不是兄弟中的老大返回节点的哥哥
		while(siblings.next()){
			newNode = siblings.getValue(this.fields.getNodeId());
			if(curNode.equals(newNode)){
				break;
			}
			brother = newNode;
		}
		return brother;
	}
	
	/**
	 * 获取平面化查询视图,获取从指定节点开始到指定层级的子节点的平面化节点信息,获取平面化视图时当前指定节点的父亲门是否有弟弟为外部传入
	 * @param sp        sql容器
	 * @param nodeId    当前节点ID
	 * @param currentNodeLevel 当前节点层级
	 * @param levelDown      查询节点以下的子节点级数
	 * @param parentsHaveLBrother 父亲门是否有弟弟
	 * @param nodeType   查询类型过滤条件
	 * @param operatorType 查询子类型过滤条件(在业务模型树中应用于主题和表两种类型的过滤)
	 */
	protected void getTreeSql(StringBuilder sp,int levelDown,String nodeId
			,String nodeType,String operatorType){
		String parent= null;
		levelDown=levelDown+1;
		parent="a1."+fields.getNodeId();
		for(int i=1;i<=levelDown;i++){
			_generatorSqlColString(sp, levelDown, i);
			sp.append(" from "+this.tableName+" a1");
			int j;
			for(j=1;j<=levelDown-i;j++){
				sp.append(" join "+tableName+" a"+(j+1));
				sp.append(" on a"+(j)+"."+fields.getNodeId()+"=a"+(j+1)+"."+fields.getNodeParent()+" ");
			}
			sp.append("  where "+parent+"='"+nodeId+"'");
			if(nodeType!=null){
				sp.append(" and a"+(j)+"."+fields.getNodeType()+"='"+nodeType+"'");
			}
			if(operatorType!=null){
				sp.append(" and a"+(j)+"."+fields.getOperatorType()+"<'"+operatorType+"'");
			}
			if(i<levelDown){
				sp.append(" \n union \n");
			}
		}
	}

	/**
	 *根据字段数据目、字段名称和树深度生成字段查询Sql  
	 */
	private void _generatorSqlColString(StringBuilder sp,int depth,int i){
		ArrayList<String> columns=_generatorSqlCol(depth, i);
		//按照查询顺序生存查询字符串,字段间用逗号隔开
		sp.append("select ");
		for(int j=0;j<columns.size()-1;j++){
			if(depth==1&&j==columns.size()-1){
				sp.append(columns.get(j)+" ");
			}else{
				sp.append(columns.get(j)+",");
			}
		}
		//虚拟当前查询节点级别
		sp.append(columns.get(columns.size()-1));
	}

	/**
	 * 生成查询字段的SQL  
	 */
	private ArrayList<String> _generatorSqlCol(int depth,int i){
		ArrayList<String> columns=new ArrayList<String>();
		String id="a"+(depth-i+1)+"."+fields.getNodeId();
		columns.add(id);
		String parent="a"+(depth-i+1)+"."+fields.getNodeParent();
		columns.add(parent);
		String name="a"+(depth-i+1)+"."+fields.getNodeName()+"";
		columns.add(name);
		String sequence="a"+(depth-i+1)+"."+fields.getNodeSequence()+"";
		columns.add(sequence);
		String opt="a"+(depth-i+1)+"."+fields.getOperatorType()+"";
		columns.add(opt);
		String desc="a"+(depth-i+1)+"."+fields.getNodeDesc()+"";
		columns.add(desc);
		String realId="a"+(depth-i+1)+"."+fields.getRealId()+"";
		columns.add(realId);
		if(fields.getNodeType()!=null){
			String nodeType="a"+(depth-i+1)+"."+fields.getNodeType()+"";
			columns.add(nodeType);
		}
		String nodeLevel=(depth-i+1)+" "+fields.getNodeLevel()+"";
		columns.add(nodeLevel);
		return columns;
	}
}
